/* ------------------------------------------
*   Copyright (c) [2022] [R.H.Shen]
*   [SC4AC] is licensed under Mulan PSL v2.
*   You can use this software according to the terms and conditions of the Mulan
*   PSL v2.
*   You may obtain a copy of Mulan PSL v2 at:
*              http://license.coscl.org.cn/MulanPSL2
*   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
*	KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
*	NON-INFRINGEMENT, *	MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*   See the Mulan PSL v2 for more details.
---------------------------------------------- */

#include "Stream.h"

#include <iostream>

Stream::Stream(int initCapacity) {
  buffer = new char[initCapacity];
  capacity = initCapacity;
  start = 0;
  length = 0;
}

Stream::~Stream() { delete[] buffer; }

int Stream::getLength() { return length; }

void Stream::append(char aChar) {
  if (length >= capacity) expand();
  int pos = start + length;
  if (pos >= capacity) pos -= capacity;
  buffer[pos] = aChar;
  length++;
}

void Stream::append(const char *buf, int len) {
  for (int i = 0; i < len; i++) append(buf[i]);
}

char Stream::peek() {
  if (length == 0) return 0;
  return buffer[start];
}

// 查看流开头的多个字符，返回实际查看到的长度
int Stream::peek(char *buf, int len) {
  if (len > length)  // len为流的长度
    len = length;
  for (int i = 0; i < len; i++) {
    int pos = start + i;
    if (pos >= capacity) pos -= capacity;
    buf[i] = buffer[pos];
  }
  return len;
}

// 取出流的第一个字符，如果长度为0则返回0
char Stream::take() {
  // std::cout <<"stream take 进来了";

  if (length == 0) return 0;
  char aChar = buffer[start];
  start++;
  length--;
  if (start >= capacity) start -= capacity;
  return aChar;
  // std::cout <<"stream take 退出了";
}

// 取出流开头的多个字符，返回实际取出的长度
int Stream::take(char *buf, int len) {
  if (len > length) len = length;
  for (int i = 0; i < len; i++) buf[i] = take();
  return len;
}

void Stream::expand() {
  int newCapacity = capacity * 2;
  char *newBuf = new char[newCapacity];
  int newLength = length;
  take(newBuf, newLength);
  delete[] buffer;
  buffer = newBuf;
  capacity = newCapacity;
  start = 0;
  length = newLength;
}